#import "BLEManager.h"

typedef NS_ENUM(int, BLEDisconnetMode) {
	BLEDisconnetModeManual		,		//手动断开
	BLEDisconnetModeTimeout		,		//超时
	BLEDisconnetModePoweredOff	,		//关闭蓝牙
};

typedef NS_ENUM(int, BLEConnectError) {
	BLEConnectErrorTimeout		= 1,	//超时连接
	BLEConnectErrorCharacteristic	,	//未检测到有效特征
};

//=============================================================
@class BLEDevice;

#pragma mark - 设备代理协议
@protocol BLEDeviceDelegate <NSObject>
@optional

- (void)device:(BLEDevice *)device didUpdateRSSI:(NSInteger)rssi;					//设备已更新信号强度
- (void)device:(BLEDevice *)device didConnectedWithError:(NSError *)error;			//设备连接完成，若无错误则连接成功
- (void)device:(BLEDevice *)device didDisconnectedWithMode:(BLEDisconnetMode)mode;	//设备已断开连接（人为断开、蓝牙关闭、重连失败后）

- (void)device:(BLEDevice *)device didFailedSend:(NSData *)data;		//数据发送失败
- (void)device:(BLEDevice *)device didUpdateData:(NSData *)data;		//成功接收新数据

@end

#pragma mark - 子类处理协议
@protocol BLEDeviceProtocol
@optional

- (void)serivce:(CBService *)serivce didDiscoverCharacteristics:(CBCharacteristic *)characteristic;		//指定服务发现特征
- (void)characteristic:(CBCharacteristic *)characteristic didUpdateData:(NSData *)data;					//特征已更新数据

- (void)didConnected;			//设备已连接成功
- (void)willReconnect;			//设备将要重新连接（非人为断开时会启用重连机制）
- (void)didDisconnected;		//设备已断开连接（人为断开、蓝牙关闭、重连失败后）

- (void)didFailedSend:(NSData *)data;		//数据发送失败
- (BOOL)shouldUpdateData:(NSData *)data;	//通知子类进行数据处理，若符合子类要求，子类应返回YES，否则NO进行重发

- (void)didAdvertisement;		//已更新广播

@end

#pragma mark - 通用蓝牙设备
/*=============================================================
 说明：
	蓝牙设备类，用于所有外设对象。（实现自动重连、数据重发）
 ============================================================*/
@interface BLEDevice : NSObject <CBPeripheralDelegate>

- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithPeripheral:(CBPeripheral *)peripheral inManager:(BLEManager *)manger;

@property (nonatomic, assign)   id<BLEDeviceDelegate>   delegate;

@property (nonatomic, readonly) BLEManager		*manager;		//管理器
@property (nonatomic, readonly) CBPeripheral	*peripheral;	//外设
@property (nonatomic, assign)	NSInteger		tag;

//服务特征
@property (nonatomic, retain) NSArray <CBUUID *>	*services;	//当前设备需要操作的服务（第一个为数据通讯服务）
@property (nonatomic, retain) NSDictionary <CBUUID *, NSArray <CBUUID *> *>	*characteristics;		//对应服务包含的特征UUID(特征是数组，若为nil则根据属性自动识别，否则第一个为接收特征，最后一个为发送特征）

//蓝牙信息
@property (nonatomic, readonly) NSDictionary	*advertisement;	//广播数据
@property (nonatomic, readonly) int				rssi;			//信号强度
@property (nonatomic, readonly) int				rssiLevel;		//信号强度等级（0:无信号或很低 1~4:数字越大信号越强）

//蓝牙状态
@property (nonatomic, readonly) BOOL			connected;		//已连接
@property (nonatomic, readonly) BOOL			connecting;		//连接中（若connected为YES，同时connecting也为YES，说明设备断开重连中）

- (void)connect;			//连接设备
- (void)disconnect;			//断开设备

#pragma mark - 收发器
//若不设置txd、rxd特征，则BLEDevice的子类必须正确设置 services, 类中根据 services.firstObject 自动获取特征
@property (nonatomic, retain)	CBCharacteristic	*txd;		//发送特征（自动获取 services.firstObject 包含写入属性的特征，可手动设置）
@property (nonatomic, retain)	CBCharacteristic	*rxd;		//接收特征（自动获取 services.firstObject 包含通知属性的特征，可手动设置）

@property (nonatomic, readonly) NSMutableArray <NSData *>	*commands;		//命令对列
@property (nonatomic, readonly) BOOL    sending;		//发送中

- (void)clearSend;			//清除当前设备的所有发送指令
- (void)sendData:(NSData *)data;		//发送数据

@end

#pragma mark - 运动秀通用设备代理协议
@class FSBLEDevice;

@protocol FSBLEDeviceDelegate <BLEDeviceDelegate>
@optional

- (void)device:(FSBLEDevice *)device didReadyWithError:(NSError *)error;	//设备已就绪（已完成必要的通讯）, 超时将返回错误
- (void)device:(FSBLEDevice *)device didStartWithError:(NSError *)error;	//设备完成启动（若error非nil，则启动失败）
- (void)device:(FSBLEDevice *)device didError:(NSError *)error;				//设备发生故障

- (void)device:(FSBLEDevice *)device newState:(int)newState oldState:(int)oldState;		//设备状态改变

@end

#pragma mark - 运动秀通用蓝牙设备（跑步机、健身车等为此子类）
@class FSDevice;
@interface FSBLEDevice : BLEDevice <BLEDeviceProtocol>

- (instancetype)initWithDevice:(BLEDevice *)device;

@property (nonatomic, assign) id<FSBLEDeviceDelegate>	delegate;

@property (nonatomic, readonly) FSDevice		*device;	//设备信息
@property (nonatomic, readonly) NSError			*error;		//设备故障

- (BOOL)checkData:(NSData *)data;		//校验（起始符、校验码、终止符），若成功返回YES
- (void)sendData:(Byte *)data length:(NSUInteger)length;	//发送数据，此方法自动合成起始符、校验码、终止符

//设备操作
- (void)start;
- (void)pause;
- (void)stop;

@end
